﻿#region << 版 本 注 释 >>
/*----------------------------------------------------------------
 * 版权所有 (c) 2022 北京超维景生物科技有限公司 保留所有权利。
 * 
 * 创建者：huangyang
 * 电子邮箱：huangyang@tvscope.cn
 * 创建时间：2023/3/13 17:46:41
 * 版本：V1.0.0
 * 描述：
 *
 * ----------------------------------------------------------------
 * 修改人：
 * 时间：
 * 修改说明：
 *
 * 版本：V1.0.1
 *----------------------------------------------------------------*/
#endregion << 版 本 注 释 >>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ImageK.Java;

namespace ImageK.Gui
{
    /**Custom component for displaying multiple lines. Based on 
   MultiLineLabel class from "Java in a Nutshell" by David Flanagan.*/
    public class MultiLineLabel : Label
    {
        string []
        lines;
	    int num_lines;
	    int margin_width = 6;
	    int margin_height = 6;
	    int line_height;
	    int line_ascent;
	    int[]
            line_widths;
	    int min_width, max_width;

        // Breaks the specified label up into an array of lines.
        public MultiLineLabel(string label)
        {
            init(label);
        }

        public MultiLineLabel(string label, int minimumWidth)
        {
            init(label);
            min_width = minimumWidth;
        }

        private void init(string text)
        {
            lines = text.Split("\n");
            num_lines = lines.Length;
        }

        // Figures out how wide each line of the label
        // is, and how wide the widest line is.
        protected void measure()
        {
            Font font = this.Font;
            FontMetrics fm = font != null ? new FontMetrics(this.CreateGraphics(), font) : null;
            // If we don't have font metrics yet, just return.
            if (fm == null) return;
            line_height = fm.getHeight();
            line_ascent = fm.getAscent();
            max_width = 0;
            for (int i = 0; i < num_lines; i++)
            {
                line_widths[i] = (int)fm.StringWidth(lines[i]);
                if (line_widths[i] > max_width) max_width = line_widths[i];
            }
        }


        public void setText(string text)
        {
            init(text);
            measure();
            Invalidate();
        }

        public void setFont(Font f)
        {
            this.Font = f;
            measure();
            Invalidate();
        }


        // This method is invoked after our Canvas is first created
        // but before it can actually be displayed.  After we've
        // invoked our superclass's addNotify() method, we have font
        // metrics and can successfully call measure() to figure out
        // how big the label is.
        public void addNotify()
        {
            // base.addNotify();
            measure();
        }


        // Called by a layout manager when it wants to
        // know how big we'd like to be.  
        public Size getPreferredSize()
        {
            return new Size(Math.Max(min_width, max_width + 2 * margin_width),
                         num_lines * line_height + 2 * margin_height);
        }


        // Called when the layout manager wants to know
        // the bare minimum amount of space we need to get by.
        public Size getMinimumSize()
        {
            return new Size(Math.Max(min_width, max_width), num_lines * line_height);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            paint(e.Graphics);
        }

        // Draws the label
        public void paint(Graphics g)
        {
            int x, y;
            Size d = this.Size;
            if (!IJ.isLinux()) setAntialiasedText(g);
            y = line_ascent + (d.Height - num_lines * line_height) / 2;
            for (int i = 0; i < num_lines; i++, y += line_height)
            {
                x = margin_width;
                g.DrawString(lines[i], Font, new SolidBrush(this.ForeColor), x, y);
            }
        }

        void setAntialiasedText(Graphics g)
        {
            // Graphics2D g2d = (Graphics2D)g;
            // g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        }

    }

}
